name: AutoGPT Docker CI

on:
  push:
    branches: [ master, development ]
    paths:
      - '.github/workflows/autogpt-docker-ci.yml'
      - 'autogpts/autogpt/**'
      - '!autogpts/autogpt/tests/vcr_cassettes'
  pull_request:
    branches: [ master, development, release-* ]
    paths:
      - '.github/workflows/autogpt-docker-ci.yml'
      - 'autogpts/autogpt/**'
      - '!autogpts/autogpt/tests/vcr_cassettes'

concurrency:
  group: ${{ format('autogpt-docker-ci-{0}', github.head_ref && format('pr-{0}', github.event.pull_request.number) || github.sha) }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

defaults:
  run:
    working-directory: autogpts/autogpt

env:
  IMAGE_NAME: auto-gpt
  DEPLOY_IMAGE_NAME: ${{ secrets.DOCKER_USER && format('{0}/', secrets.DOCKER_USER) || '' }}auto-gpt
  DEV_IMAGE_TAG: latest-dev

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        build-type: [release, dev]
    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v3

    - if: runner.debug
      run: |
        ls -al
        du -hs *

    - id: build
      name: Build image
      uses: docker/build-push-action@v5
      with:
        context: autogpts/autogpt
        build-args: BUILD_TYPE=${{ matrix.build-type }}
        tags: ${{ env.IMAGE_NAME }}
        labels: GIT_REVISION=${{ github.sha }}
        load: true    # save to docker images
        # cache layers in GitHub Actions cache to speed up builds
        cache-from: type=gha,scope=autogpt-docker-${{ matrix.build-type }}
        cache-to: type=gha,scope=autogpt-docker-${{ matrix.build-type }},mode=max

    - name: Generate build report
      env:
        event_name: ${{ github.event_name }}
        event_ref: ${{ github.event.ref }}
        event_ref_type: ${{ github.event.ref}}

        build_type: ${{ matrix.build-type }}

        prod_branch: master
        dev_branch: development
        repository: ${{ github.repository }}
        base_branch: ${{ github.ref_name != 'master' && github.ref_name != 'development' && 'development' || 'master' }}

        current_ref: ${{ github.ref_name }}
        commit_hash: ${{ github.event.after }}
        source_url: ${{ format('{0}/tree/{1}', github.event.repository.url, github.event.release && github.event.release.tag_name || github.sha) }}
        push_forced_label: ${{ github.event.forced && '☢️ forced' || '' }}

        new_commits_json: ${{ toJSON(github.event.commits) }}
        compare_url_template: ${{ format('/{0}/compare/{{base}}...{{head}}', github.repository) }}

        github_context_json: ${{ toJSON(github) }}
        job_env_json: ${{ toJSON(env) }}
        vars_json: ${{ toJSON(vars) }}

      run: .github/workflows/scripts/docker-ci-summary.sh >> $GITHUB_STEP_SUMMARY
      working-directory: ./
      continue-on-error: true

  test:
    runs-on: ubuntu-latest
    timeout-minutes: 10

    services:
      minio:
        image: minio/minio:edge-cicd
        options: >
          --name=minio
          --health-interval=10s --health-timeout=5s --health-retries=3
          --health-cmd="curl -f http://localhost:9000/minio/health/live"

    steps:
      - name: Check out repository
        uses: actions/checkout@v4
        with:
          submodules: true

      - if: github.event_name == 'push'
        name: Log in to Docker hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USER }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - id: build
        name: Build image
        uses: docker/build-push-action@v5
        with:
          context: autogpts/autogpt
          build-args: BUILD_TYPE=dev  # include pytest
          tags: >
            ${{ env.IMAGE_NAME }},
            ${{ env.DEPLOY_IMAGE_NAME }}:${{ env.DEV_IMAGE_TAG }}
          labels: GIT_REVISION=${{ github.sha }}
          load: true                  # save to docker images
          # cache layers in GitHub Actions cache to speed up builds
          cache-from: type=gha,scope=autogpt-docker-dev
          cache-to: type=gha,scope=autogpt-docker-dev,mode=max

      - id: test
        name: Run tests
        env:
          CI: true
          PLAIN_OUTPUT: True
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          S3_ENDPOINT_URL: http://minio:9000
          AWS_ACCESS_KEY_ID: minioadmin
          AWS_SECRET_ACCESS_KEY: minioadmin
        run: |
          set +e
          docker run --env CI --env OPENAI_API_KEY \
            --network container:minio \
            --env S3_ENDPOINT_URL --env AWS_ACCESS_KEY_ID --env AWS_SECRET_ACCESS_KEY \
            --entrypoint poetry ${{ env.IMAGE_NAME }} run \
            pytest -v --cov=autogpt --cov-branch --cov-report term-missing \
            --numprocesses=4 --durations=10 \
            tests/unit tests/integration 2>&1 | tee test_output.txt

          test_failure=${PIPESTATUS[0]}

          cat << $EOF >> $GITHUB_STEP_SUMMARY
          # Tests $([ $test_failure = 0 ] && echo '✅' || echo '❌')
          \`\`\`
          $(cat test_output.txt)
          \`\`\`
          $EOF

          exit $test_failure

      - if: github.event_name == 'push' && github.ref_name == 'master'
        name: Push image to Docker Hub
        run: docker push ${{ env.DEPLOY_IMAGE_NAME }}:${{ env.DEV_IMAGE_TAG }}
